#include <iostream>
#include <utility>
#include <typeinfo>

using namespace std;

template <typename T>
class Foo
{
public:
	explicit Foo(T p)
		: _p(p)
	{
		cout << "Foo(T *p) with T = " << typeid(T).name() << endl;
	}

	// not implemented in VC11 Beta and gcc
//	Foo()
//		: FooT())
//	{
//		cout << "Foo()" << endl;
//	}

	Foo()
		: _p()
	{
		cout << "Foo() with T = " << typeid(T).name() << endl;
	}

	Foo(const Foo<T> &foo)
	{
		_p = foo._p;
		cout << "Foo(const Foo<T> &foo) with T = " << typeid(T).name() << endl;
	}

	Foo(Foo<T> &&foo)
	{
		swap(_p, foo._p);
		cout << "Foo(Foo<T> &&foo) with T = " << typeid(T).name() << endl;
	}

	const Foo<T> & operator=(const Foo<T> &foo)
	{
		_p = foo._p;
		cout << "const Foo<T> & operator=(const Foo<T> &foo) with T = " << typeid(T).name() << endl;
		return *this;
	}

	Foo<T> && operator=(Foo<T> &&foo)
	{
		swap(_p, foo._p);
		cout << "Foo<T> && operator=(Foo<T> &&foo) with T = " << typeid(T).name() << endl;
		return move(*this);
	}


private:
	T _p;
};

int main()
{
	Foo<int> a;

	int *k = nullptr;

	Foo<decltype(k)> b(k);

	decltype(b) c(b);

	c = b;

	auto gen1 = []()
	{
		Foo<double> ret(42.f);

		return ret;
	};

	auto moved1 = gen1();

	auto gen2 = []()
	{
		Foo<size_t> ret(42u);

		return ret;
	};

	decltype(gen2()) moved2;

	moved2 = gen2();

	cin.get();

	return 0;
}
